package com.kmb.provider.service;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.kmb.commons.utils.DateUtil;
import com.kmb.commons.utils.ExcelUtils;
import com.kmb.provider.api.SfKmUserService;
import com.kmb.provider.domain.SfKmUser;
import com.kmb.provider.mapper.SfKmUserMapper;
import com.kmb.provider.service.fallback.SfKmUserServiceFallback;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

@Service(version = "1.0.0")
public class SfKmUserServiceImpl implements SfKmUserService {

    @Resource
    private SfKmUserMapper sfKmUserMapper;
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    /**
     * 熔断器的使用
     *
     * <p>
     * 1.  {@link SentinelResource#value()} 对应的是 Sentinel 控制台中的资源，可用作控制台设置【流控】和【降级】操作 <br>
     * 2.  {@link SentinelResource#fallback()} 对应的是 {@link SfKmUserServiceFallback#getByUsernameFallback(String, Throwable)}，并且必须为 `static` <br>
     * 3. 如果不设置 {@link SentinelResource#fallbackClass()}，则需要在当前类中创建一个 `Fallback` 函数，函数签名与原函数一致或加一个 {@link Throwable} 类型的参数
     * </p>
     *
     * @param username {@code String} 用户名
     * @return {@link SfKmUser}
     */
    @Override
    @SentinelResource(value = "getByUsername", fallback = "getByUsernameFallback", fallbackClass = SfKmUserServiceFallback.class)
    public SfKmUser getByUsername(String username) {
        Example example = new Example(SfKmUser.class);
        example.createCriteria().andEqualTo("userName", username);
        return sfKmUserMapper.selectOneByExample(example);
    }

    @Override
    @SentinelResource(value = "addUser", fallback = "addUserFallback", fallbackClass = SfKmUserServiceFallback.class)
    public int addUser(SfKmUser user) {
        // password 转换
        user.setUserPassword(passwordEncoder.encode(user.getUserPassword()));
        user.setCreateTime(DateUtil.getDateNowTime());
        user.setUpdateTime(DateUtil.getDateNowTime());
        int id = sfKmUserMapper.insertUseGeneratedKeys(user);
//        int id = sfKmUserMapper.insert(user);
//        int id = userDao.addUser(user);
        // 刷新用户缓存
//        UserConfig.refreshUserMap();
        return id;
    }

    @Override
    @SentinelResource(value = "deleteUser", fallback = "deleteUserFallback", fallbackClass = SfKmUserServiceFallback.class)
    public int deleteUser(String userName) {
        Example example = new Example(SfKmUser.class);
        example.createCriteria().andEqualTo("userName", userName);
        int i = sfKmUserMapper.deleteByExample(example);
        return i;
    }

    @Override
    @SentinelResource(value = "updatePassword", fallback = "updatePasswordFallback", fallbackClass = SfKmUserServiceFallback.class)
    public int updatePassword(String password, String userName) {
        Example example = new Example(SfKmUser.class);
        example.createCriteria().andEqualTo("userName", userName);
        SfKmUser sfKmUser = sfKmUserMapper.selectOneByExample(example);
        sfKmUser.setUserPassword(passwordEncoder.encode(password));
        int i = sfKmUserMapper.updateByPrimaryKey(sfKmUser);
        return i;
    }

    @Override
    @SentinelResource(value = "importUser", fallback = "importUserFallback", fallbackClass = SfKmUserServiceFallback.class)
    public int importUser(File file) {
        List<List<String>> list = ExcelUtils.parseExcel(file);
        List<SfKmUser> sfKmUsers = new ArrayList<>();
        //user_name , user_code , user_type , real_name , email , user_password
        list.forEach(obj -> {
            SfKmUser sfKmUser = new SfKmUser();
            sfKmUser.setUserName(obj.get(0));
            sfKmUser.setUserCode(obj.get(1));
            sfKmUser.setUserType(obj.get(2));
            sfKmUser.setRealName(obj.get(3));
            sfKmUser.setEmail(obj.get(4));
            sfKmUser.setUserPassword(passwordEncoder.encode(obj.get(5)));
            sfKmUsers.add(sfKmUser);
        });
        int i = sfKmUserMapper.insertList(sfKmUsers);
        return i;
    }

    @Override
    @SentinelResource(value = "getUserList", fallback = "getUserListFallback", fallbackClass = SfKmUserServiceFallback.class)
    public List<SfKmUser> getUserList(int pageNo, int pageSize) {
        PageHelper.startPage(pageNo, pageSize);
        PageInfo<SfKmUser> pageInfo = new PageInfo<>(sfKmUserMapper.selectAll());
        pageInfo.getList().forEach(obj -> {
            //转换用户类型
            obj.setUserType("");
        });
        List<SfKmUser> list = pageInfo.getList();
        return list;
    }

}

